package node.exp;

import grammar.Lexer;
import lexical.Key;
import lexical.Word;
import midcode.MidCode;
import midcode.MidcodeGenerator;
import midcode.OPType;
import node.Node;
import symbol.SymbolTable;

import java.util.ArrayList;

public class EqExp implements Node {
    private final Lexer lexer;
    private final SymbolTable table;
    private final Node father;
    private ArrayList<Node> relExps = new ArrayList<>();
    private ArrayList<Word> calTypes = new ArrayList<>();

    public EqExp(Lexer lexer, SymbolTable table, Node father) {
        this.lexer = lexer;
        this.table = table;
        this.father = father;
        parseEqExp();
    }

    private void parseEqExp() {
        relExps.add(new RelExp(lexer, table, this));
        while (lexer.isWordType(0, Key.EQL) || lexer.isWordType(0, Key.NEQ)) {
            calTypes.add(lexer.getCurWord()); // == | !=
            relExps.add(new RelExp(lexer, table, this));
        }
    }

    @Override
    public Node getFather() {
        return father;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(relExps.get(0).toString());
        for (int i = 1; i < relExps.size(); i++) {
            sb.append(calTypes.get(i-1).toString());
            sb.append(relExps.get(i).toString());
        }
        return sb.toString();
    }

    @Override
    public String genMidCode() {
        MidcodeGenerator mg = MidcodeGenerator.getInstance();
        String tmp1 = relExps.get(0).genMidCode();
        for (int i = 1; i < relExps.size(); i++) {
            OPType op = (calTypes.get(i-1).key == Key.EQL) ? OPType.SEQ : OPType.SNE;
            String tmp2 = relExps.get(i).genMidCode();
            String tmp3;
            if (mg.isNumber(tmp1) && mg.isNumber(tmp2)) {
                int value1 = Integer.parseInt(tmp1);
                int value2 = Integer.parseInt(tmp2);
                if ((op == OPType.SEQ && value1 == value2) || (op == OPType.SNE && value1 != value2)) {
                    tmp3 = "1";
                } else {
                    tmp3 = "0";
                }
            } else {
                tmp3 = mg.genTmp();
                mg.addMidcode(new MidCode(op, tmp1, tmp2, tmp3));
            }
            tmp1 = tmp3;
        }
        return tmp1;
    }
}

